<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <button id="btn">按钮</button>
  <script>

    // 之前的
    btn.onclick = function () {
      console.log('点击的按钮')
    }
    // 想要的效果
    btn.onclick = debounce(function () {
      console.log('点击的按钮')
    }, 1000)
    

    // 分析过程:
    // btn.onclick 在绑定事件的时候,等号右侧一定给的是一个函数,当我们点击按钮的时候,这个函数会执行
    // btn.onclick = function () {}

    // 此时当我们使用防抖的时候,等号右侧放的是一个 函数调用
    // 函数调用可以理解为一个函数调用[表达式]
    // 表达式是有值的,这个函数调用的值是函数的返回值
    // 由此可得,debounce 该函数返回的一定是一个函数
    // btn.onclick = debounce()


    // 防抖函数,用来给 按钮的点击事件的回调函数进行防抖,给函数防抖
    // 参数一: 需要防抖的函数
    // 参数二: 时间(毫秒数),当点击按钮执行回调的时候,等待多少毫秒之后执行这个回调
    function debounce (fn, delay) {
      let timer = null; // 这个变量用来存定时器,是一个局部变量
      // 但是在后续的使用过程中形成了闭包,这个变量无法被回收,拿到的就是上一次存在这个变量中的内容
      // 一旦点击按钮,就会执行return这个函数
      return function() {
        if (timer) {
          clearTimeout(timer); // 清除掉上一次的定时器
        }
        // 等一会再执行fn,使用定时器来完成这个动作
        timer = setTimeout(() => {
          fn()
        }, delay)
      }
    }

    // 闭包:
    // 什么是闭包: 闭包是一种引用关系,函数内部引用了函数外部的局部变量
    // 闭包产生的条件:
    //  1. 函数的嵌套
    //  2. 函数内部引用了函数外部的局部变量
    //  3. 函数外部被调用(当外部函数被调用的时候,闭包就形成)
    //     说明:当外部函数被调用的时候,只要函数调用作用域和作用域链就形成了
    //          作用域原本因该随着函数调用的结束而不存在,但是由于条件2
    //          函数执行环境在销毁的时候不能完全销毁,剩下的残缺不全的作用域链,就是闭包

  </script>
</body>
</html>